/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       bitmap_group_window.h

	$Header: /game/bitmap_group_window.h $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "bitmap_group_window.h"

#include "bitmap_group.h"
#include "paint_surface.h"

// ----------------------------------------------------------------------
// window which displays 1 frame of a bitmap group
// ----------------------------------------------------------------------
t_bitmap_group_window::t_bitmap_group_window( t_bitmap_group_ptr const& bitmaps, t_screen_point point, 
		                                      int frame, t_window* parent )
				     : t_window( k_no_transparency, parent ), m_bitmaps( bitmaps )
{
	t_screen_rect rect = m_bitmaps->get_rect();

	if (bitmaps->get_alpha_depth() > 0)
		m_has_transparency = k_some_transparency;
	m_bitmap = &(*bitmaps)[frame];
	m_current_frame = frame;
	m_origin = rect.top_left();
	init( rect + point );
}

t_bitmap_group_window::t_bitmap_group_window( t_bitmap_group_ptr const& bitmaps, 
											  t_screen_point point,
											  std::string const& layer_name, t_window* parent )
				     : t_window( k_no_transparency, parent ), m_bitmaps( bitmaps )
{
	t_screen_rect rect = m_bitmaps->get_rect();

	if (bitmaps->get_alpha_depth() > 0)
		m_has_transparency = k_some_transparency;
	
	t_bitmap_group::const_iterator index = bitmaps->find_iterator( layer_name );

	m_bitmap = index->get();
	m_current_frame = index - bitmaps->begin();
	m_origin = rect.top_left();
	init( rect + point );
}

// ----------------------------------------------------------------------
// window which displays 1 frame of a bitmap group
// ----------------------------------------------------------------------
int t_bitmap_group_window::get_frame_count() const
{
	return m_bitmaps->size();
}

// ----------------------------------------------------------------------
// window which displays 1 frame of a bitmap group
// ----------------------------------------------------------------------
bool t_bitmap_group_window::is_contained( t_screen_point point ) const
{
	if (!is_point_in_rect( point, get_client_rect() ))
		return false;
	if (!m_has_transparency)
		return true;
	return m_bitmap->contains( point + m_origin );
}

// ----------------------------------------------------------------------
// window which displays 1 frame of a bitmap group
// ----------------------------------------------------------------------
void t_bitmap_group_window::paint( t_paint_surface& paint_surface )
{
	t_abstract_bitmap16_ptr	dest = paint_surface.get_bitmap();
	t_screen_rect           dest_rect = paint_surface.get_rect();
	t_screen_point          dest_point(0,0);
	t_screen_rect           source_rect = dest_rect + m_origin;

	m_bitmap->draw_to( source_rect, *dest, dest_point );
}

// ----------------------------------------------------------------------
// window which displays 1 frame of a bitmap group
// ----------------------------------------------------------------------
void t_bitmap_group_window::set_bitmaps( t_bitmap_group_ptr const& bitmaps, int frame )
{
	// change the bitmaps for the window.
	bool           was_visible = is_visible();
	t_screen_point point = get_screen_rect().top_left();
	t_screen_rect  rect;

	// hide the window because we are possibly changing the transparency level.
	set_visible( false );
	m_has_transparency = k_no_transparency;
	if (bitmaps->get_alpha_depth() > 0)
		m_has_transparency = k_some_transparency;
	// set the variables.
	m_bitmaps = bitmaps;
	m_bitmap = (bitmaps->begin() + frame)->get();
	m_current_frame = frame;

	// compute the new rectangle.
	rect = bitmaps->get_rect();
	m_origin = rect.top_left();
	rect = get_parent()->to_client( rect + point );
	move( rect );
	// show it again if it was visible.
	set_visible( was_visible );
	get_parent()->update_size();
}

// ----------------------------------------------------------------------
// window which displays 1 frame of a bitmap group
// ----------------------------------------------------------------------
void t_bitmap_group_window::set_frame( int frame )
{
	if (frame == m_current_frame)
		return;
	assert( frame < m_bitmaps->size() );

	invalidate( m_bitmap->get_rect() - m_origin );  // invalidate old rectangle
	m_current_frame = frame;
	m_bitmap = (m_bitmaps->begin() + frame)->get();
	invalidate( m_bitmap->get_rect() - m_origin );  // invalidate new rectangle
}	

// ----------------------------------------------------------------------
// window which displays 1 frame of a bitmap group
// ----------------------------------------------------------------------
void t_bitmap_group_window::set_frame( std::string const& name )
{
	t_bitmap_group::const_iterator index = m_bitmaps->find_iterator( name );

	if (index == m_bitmaps->end())
		return;
	set_frame( index - m_bitmaps->begin() );
}


void t_bitmap_group_window::set_size_from_frame()
{
	t_screen_rect  rect = m_bitmap->get_rect();
	t_screen_point position = get_screen_rect().top_left();

	position += rect.top_left() - m_origin;
	m_origin = rect.top_left();
	rect -= m_origin;
	rect += position;
	move_screen_rect( rect );
}
